﻿using LuShanTea.Common;
using LuShanTea.DTO;
using LuShanTea.IService;
using LuShanTea.Service.Entities;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LuShanTea.Service
{
    public class UserService : IUserService
    {
        /// <summary>
        /// 添加用户
        /// </summary>
        /// <param name="userAddNewDTO"></param>
        /// <returns></returns>
        public long AddNew(UserAddNewDTO userAddNewDTO)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                //数据检查应在控制器中完成调用GetByPhoneNum(string phoneNum) 和 GetByEmail(string email)

                User user = new User()
                {
                    Email = userAddNewDTO.Email,
                    Gender = userAddNewDTO.Gender,
                    NiceName = userAddNewDTO.NickName,
                    Name = userAddNewDTO.Name,
                    PhoneNumber = userAddNewDTO.PhoneNum,
                    ImgSrc = userAddNewDTO.ImgSrc
                };

                user.Salt = CommonHelper.GetSalt();
                user.HashPwd = CommonHelper.CalcMD5(userAddNewDTO.Pwd + user.Salt);

                context.Users.Add(user);

                context.SaveChanges();

                return user.Id;

            }
        }

        public long GetTotalCount()
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<User> baseService = new BaseService<User>(context);

                return baseService.GetAll().LongCount();

            }
        }


        /// <summary>
        /// 检查用户
        /// </summary>
        /// <param name="phoneNum">用户手机号</param>
        /// <param name="pwd">密码</param>
        /// <returns></returns>
        public bool CheckLogin(string account, string pwd)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<User> baseService = new BaseService<User>(context);

                User user = baseService.GetAll().SingleOrDefault(u => u.PhoneNumber == account || u.Email == account);

                if (user == null)
                {
                    return false;
                }

                string hashPwd = CommonHelper.CalcMD5(pwd + user.Salt);

                return hashPwd == user.HashPwd;

            }
        }

        /// <summary>
        /// 获取所有数据
        /// </summary>
        /// <returns></returns>
        public UserDTO[] GetAll()
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<User> baseService = new BaseService<User>(context);

                return baseService.GetAll().ToList()
                    .Select(u => ToDTO(u)).ToArray();

            }
        }

        /// <summary>
        /// 根据Id获取用户
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public UserDTO GetById(long userId)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<User> baseService = new BaseService<User>(context);

                User user = baseService.GetById(userId);

                return user == null ? null : ToDTO(user);

            }
        }

        /// <summary>
        /// 根据手机号获取用户
        /// </summary>
        /// <param name="phoneNum">手机号</param>
        /// <returns></returns>
        public UserDTO GetByPhoneNum(string phoneNum)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<User> baseService = new BaseService<User>(context);

                User user = baseService.GetAll().SingleOrDefault(u => u.PhoneNumber == phoneNum);

                return user == null ? null : ToDTO(user);

            }
        }

        /// <summary>
        /// 根据邮件获取用户
        /// </summary>
        /// <param name="email">邮箱</param>
        /// <returns></returns>
        public UserDTO GetByEmail(string email)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<User> baseService = new BaseService<User>(context);

                User user = baseService.GetAll().SingleOrDefault(u => u.Email == email);

                return user == null ? null : ToDTO(user);

            }
        }

        public UserDTO[] GetPageData(int pageSize, int pageIndex)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<User> baseService = new BaseService<User>(context);

                var users = baseService.GetAll()
                        .AsNoTracking().OrderBy(o => o.Id)
                        .Skip((pageIndex - 1) * pageSize).Take(pageSize);

                return users.ToList().Select(o => ToDTO(o)).ToArray();
            }
        }

        /// <summary>
        /// 更新用户信息
        /// </summary>
        /// <param name="userUpdateDTO"></param>
        public void Update(UserUpdateDTO userUpdateDTO)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<User> baseService = new BaseService<User>(context);

                User user = baseService.GetById(userUpdateDTO.Id);

                if (user == null)
                {
                    throw new ArgumentException(string.Format($"用户Id为：{userUpdateDTO.Id}不存在"));
                }

                user.ImgSrc = userUpdateDTO.ImgSrc;
                user.NiceName = userUpdateDTO.NickName;
                user.Name = userUpdateDTO.Name;
                user.Gender = userUpdateDTO.Gender;
                user.PhoneNumber = userUpdateDTO.PhoneNum;
                user.Email = userUpdateDTO.Email;
                context.SaveChanges();
            }
        }

        /// <summary>
        /// 更新用户密码
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <param name="oldPwd">原始密码</param>
        /// <param name="newPwd">新的密码</param>
        /// <returns></returns>
        public bool UpdatePwd(long userId, string oldPwd, string newPwd)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<User> baseService = new BaseService<User>(context);

                User user = baseService.GetById(userId);

                if (user == null)
                {
                    throw new ArgumentException(string.Format($"用户Id为：{userId}不存在"));
                }

                string hashPwd = CommonHelper.CalcMD5(oldPwd + user.Salt);

                if (hashPwd != user.HashPwd)
                {
                    return false;
                }

                user.HashPwd = CommonHelper.CalcMD5(newPwd + user.Salt);

                context.SaveChanges();
                return true;

            }
        }

        /// <summary>
        /// 软删除数据
        /// </summary>
        /// <param name="userId">用户Id</param>
        public void MarkDeleted(long userId)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<User> baseService = new BaseService<User>(context);

                User user = baseService.GetById(userId);

                if (user == null)
                {
                    throw new ArgumentException(string.Format($"用户Id为：{userId}不存在"));
                }

                baseService.MakeDelete(userId);
            }
        }

        private UserDTO ToDTO(User user)
        {
            return new UserDTO()
            {
                Id = user.Id,
                CreateDateTime = user.CreateDateTime,
                Email = user.Email,
                Gender = user.Gender,
                ImgSrc = user.ImgSrc,
                Name = user.Name,
                NiceName = user.NiceName,
                PhoneNumber = user.PhoneNumber,
                LoginErrorCount = user.LoginErrorCount,
                LoginErrorTime = user.LoginErrorTime
            };
        }

        public UserDTO GetByEmailOrPhoneNum(string email, string phoneNum)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<User> baseService = new BaseService<User>(context);

                User res = baseService.GetAll().AsNoTracking().SingleOrDefault(e => e.Email == email || e.PhoneNumber == phoneNum);
                return res == null ? null : ToDTO(res);
            }
        }

        public long GetIdByEmailOrPhoneNum(string email, string phoneNum)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<User> baseService = new BaseService<User>(context);

                User res = baseService.GetAll().AsNoTracking().SingleOrDefault(e => e.Email == email || e.PhoneNumber == phoneNum);
                if (res == null)
                {
                    throw new ArgumentException("参数异常");
                }
                return res.Id;
            }
        }

        public void RetrievePwd(long userId, string newPwd)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<User> baseService = new BaseService<User>(context);

                User user = baseService.GetById(userId);

                if (user == null)
                {
                    throw new ArgumentException(string.Format($"用户Id为：{userId}不存在"));
                }
                user.HashPwd = CommonHelper.CalcMD5(newPwd + user.Salt);
                context.SaveChanges();
            }
        }

        public void LockUser(long userId)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<User> bs = new BaseService<User>(context);
                var user = bs.GetById(userId);
                if (user == null)
                {
                    throw new ArgumentException("找不到id=" + userId + "的用户");
                }
                user.LoginErrorCount = user.LoginErrorCount + 1;
                user.LoginErrorTime = DateTime.Now;
                context.SaveChanges();
            }
        }

        public void UnLockUser(long userId)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<User> bs = new BaseService<User>(context);
                var user = bs.GetById(userId);
                if (user == null)
                {
                    throw new ArgumentException("找不到id=" + userId + "的用户");
                }
                user.LoginErrorCount = 0;
                context.SaveChanges();
            }
        }

        public bool CheckIsLock(long userId)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<User> bs = new BaseService<User>(context);
                var user = bs.GetById(userId);
                if (user == null)
                {
                    throw new ArgumentException("找不到id=" + userId + "的用户");
                }
                return (user.LoginErrorCount >= 5 && (DateTime.Now.AddMinutes(-30) < user.LoginErrorTime)) ? true : false;
            }
        }
    }
}
